import { ClientRectObject } from '@floating-ui/vue';

export const generateBoundingClientRect =
  (x = 0, y = 0) =>
  (): ClientRectObject => ({
    x,
    y,
    top: y,
    left: x,
    width: 0,
    right: x,
    height: 0,
    bottom: y,
  });

export function debounce<T extends unknown[]>(
  fn: (...args: T) => void,
  delay: number,
) {
  let timeoutId: NodeJS.Timeout;

  return (...args: T) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => {
      fn(...args);
    }, delay);
  };
}

export function wrapInParenthesis(text: string) {
  let wrappedText = text;

  if (!text.startsWith('(')) wrappedText = `(${wrappedText}`;
  if (!text.endsWith(')')) wrappedText = `${wrappedText})`;

  return wrappedText;
}

export function downloadFile(filename: string, blob: Blob | string) {
  const isString = typeof blob === 'string';
  const objectURL = isString ? blob : URL.createObjectURL(blob);

  const anchorEl = document.createElement('a');
  anchorEl.href = objectURL;
  anchorEl.download = filename;

  document.body.appendChild(anchorEl);

  anchorEl.click();
  anchorEl.remove();

  if (!isString) URL.revokeObjectURL(objectURL);
}

export function parseURL(url: string) {
  try {
    return new URL(url);
  } catch (error) {
    return null;
  }
}

export function copyToClipboard(text: string) {
  return navigator.clipboard.writeText(text);
}

export function parseJSON<T = unknown, K = unknown>(
  input: string,
  def?: K,
): T | K {
  try {
    return JSON.parse(input) as T;
  } catch (_error) {
    return def;
  }
}

export function isObject<T>(input: T) {
  return typeof input === 'object' && !Array.isArray(input);
}

export function setItem(key: string, value: unknown) {
  return new Promise<void>((resolve, reject) => {
    const data: Record<string, unknown> = {};
    data[key] = value;
    chrome.storage.local.set(data, () => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError);
      } else {
        resolve();
      }
    });
  });
}

export function getItem(key: string) {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get(key, (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError);
      } else {
        resolve(result[key] || null);
      }
    });
  });
}

export function generateUUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
    /[xy]/g,
    (c: string) => {
      const r = (Math.random() * 16) | 0;
      const v = c === 'x' ? r : (r & 0x3) | 0x8;
      return v.toString(16);
    },
  );
}

export function simulateTyping(
  inputBox: HTMLInputElement | HTMLTextAreaElement,
  text: string,
) {
  let i = 0;

  function type() {
    if (i < text.length) {
      const typingSpeed = Math.floor(Math.random() * (500 - 50 + 1)) + 50;

      // 强制设置焦点，确保输入框激活
      inputBox.focus();
      inputBox.value += text.charAt(i);
      // 模拟偶尔的删除和修正
      if (Math.random() < 0.1 && i > 0) {
        // 删除一个字符，稍作停顿，再重新输入正确字符
        inputBox.value = inputBox.value.slice(0, -1);
        const event = new Event('input', { bubbles: true });
        inputBox.dispatchEvent(event);
        setTimeout(type, typingSpeed);
        return;
      }

      // 触发input事件
      const event = new Event('input', { bubbles: true });
      inputBox.dispatchEvent(event);
      i++;
      setTimeout(type, typingSpeed);
    }
  }
  type();
}

export async function getTextFromClipboard() {
  try {
    const clipboardText = await navigator.clipboard.readText();
    return clipboardText;
  } catch (error) {
    console.error('无法读取剪切板内容:', error);
    return '';
  }
}

export function startTyping() {
  const inputBox = document.activeElement as HTMLTextAreaElement;
  if (
    inputBox &&
    (inputBox.tagName === 'INPUT' || inputBox.tagName === 'TEXTAREA')
  ) {
    inputBox.focus();
    getTextFromClipboard().then((text) => {
      if (text && text.length) {
        simulateTyping(inputBox, text);
      }
    });
  }
}
